
import { initState } from './observe'
import Watcher from './observe/watcher';
import { complier } from './util'

/**
 * 
 * @param {*} options 用户传入的数据
 */
function Vue(options){
  this._init(options); // 初始化vue
  
}

Vue.prototype._init = function(options){
  // vue中的初始化 this.$options 表示vue中的参数
  let vm = this;
  vm.$options = options;

  // MVVM原理 需要将数据重新初始化
  initState(vm); // data computed watch

  // 初始化工作
  if (vm.$options.el) {
    vm.$mount()
  }

}

/**
 * 获取dom节点
 * @param {*} el 
 */
function query(el){
  if (typeof el === 'string') {
    return document.querySelector(el);
  }
  // 传的是dom节点
  return el;
}



Vue.prototype._update = function(){
  console.log('更新次数')
  // 用用户传入的数据，去更新视图
  let vm = this;
  let el = vm.$el;
  // 要循环这个元素，将里面的内容 换成我们的数据
  
  // ---------------------以下逻辑会用虚拟dom重写
  // 需要匹配{{}}进行替换
  let node = document.createDocumentFragment();
  let firstChild
  while(firstChild = el.firstChild){ // 每次拿到第一个元素，就将元素放到fragment中
    node.appendChild(firstChild); // appendChild
  }

  // 对fragment进行处理， 对{{}}进行替换
  complier(node, vm)
  
  el.appendChild(node)
}

// 渲染yem
Vue.prototype.$mount = function(){
  let vm = this;
  let el = vm.$options.el; // 获取元素
  el = vm.$el = query(el); // 获取当前挂载的节点

  // 渲染是通过， watcher来渲染的
  // 渲染watcher  
  // vue2.0 组件级别更新

  // 更新组件，渲染的逻辑
  let updateComponent = () => {
    vm._update(); // 更新组件
  }

  new Watcher(vm, updateComponent);

  // 需要让数据更改了，重新

}

/**
 * expr 方法名
 * handler 方法实现
 */
Vue.prototype.$watch = function(expr, handler){
  // 原理 创建一个watcher  user: true用户自己定义的
  let vm = this
  new Watcher(vm, expr, handler, {user: true})
}


export default Vue